/**
 * 
 */
package edu.hunau.dom;
import java.io.FileWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;

/**
 * 采用dom生成和解析xml文档
 */
public class Xml4Dom {
	@Test
	public void testCreate() throws Exception {
		createXML();

	}

	@Test
	public void testParseXML()throws Exception{
		parseXML();
	}

	/**
	 * 使用DOM解析指定的XML文档
	 * 
	 * @throws Exception
	 */
	public static void parseXML() throws Exception {
		// 1.获得Document创建工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		// 2.通过工厂对象获得Document的创建对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		// 3.解析指定的文档获得Document对象
		Document document = builder.parse("./src/main/resources/students.xml");
		NodeList childs = document.getElementsByTagName("student");
		System.out.println(childs);
		System.out.println("student节点数:" + childs.getLength());
		Node firstStu = childs.item(0);// 获得第一个节点
		// 获得节点名称
		System.out.println(firstStu.getNodeName());
		// 获得属性
		System.out.println(firstStu.getAttributes());
		System.out.println(firstStu.getAttributes().getNamedItem("id"));
		System.out.println(firstStu.getFirstChild().getNodeName());
		System.out.println(firstStu.getFirstChild().getNextSibling()
				.getNodeName());
	}

	/**
	 * 使用DOM生成一个XML文档
	 * 
	 * @throws Exception
	 **/
	public static void createXML() throws Exception {
		// 1.获得Document创建工厂对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		// 2.通过工厂对象获得Document的创建对象
		DocumentBuilder builder = builderFactory.newDocumentBuilder();

		// 3.通过Document的创建对象获得Document对象
		Document document = builder.newDocument();

		/**********************************
		 * 通过DocumentAPI创建节点
		 * *********************************/
		// 1.创建根元素students
		Element root = document.createElement("students");

		// // 定义注释
		// Comment comment = document.createComment("表示子节点");
		//
		// root.appendChild(comment);
		// 2.创建子节点student
		Element student = document.createElement("student");
		// 2.1 为student元素提供id属性
		student.setAttribute("id", "s1001");

		// 2.2创建name子元素
		Element name = document.createElement("name");
		name.setTextContent("haoren");
		// 2.3创建gender子元素
		Element gender = document.createElement("gender");
		gender.setAttribute("value", "male");

		// 2.4student追加子节点
		student.appendChild(name);
		student.appendChild(gender);

		// 3.将student元素作为root的子节点
		root.appendChild(student);
		// 3.1 将根节点加入到文档对象中
		document.appendChild(root);

		/**************************************
		 * 将内存中构建的document解析成xml文件
		 **************************************/
		// 1.获得一个实现DOM的工厂对象
		DOMImplementationRegistry registry = DOMImplementationRegistry
				.newInstance();
		// 2.获得一个创建 Load 和 Save 对象
		// DOMImplementationLS 包括创建 Load 和 Save 对象的工厂方法
		DOMImplementationLS implementLs = (DOMImplementationLS) registry
				.getDOMImplementation("LS");
		// 3.获得输出流
		LSOutput output = implementLs.createLSOutput();
		// 4.获得序列化对象
		LSSerializer lss = implementLs.createLSSerializer();
		// 4.1 设定输出的格式为可读型的
		lss.getDomConfig().setParameter("format-pretty-print", true);
		// 5.定义一个文件对象声明文件的名称
		FileWriter file = new FileWriter("./src/main/resources/students.xml");
		// 6.将输出流设定到指定的文件中
		output.setCharacterStream(file);
		// 7.调用序列化对象将输出流写入到指定的文件
		lss.write(document, output);

	}

}
